1# Migrating [Universal Modules][universal-modules] to TypeScript 2 3- [Change Import](#change-import) 4- [Testing](#testing) 5 - [Add the tests to CI](#add-the-tests-to-ci) 6- [Move native `dependencies` to `peerDependencies`](#move-native--dependencies--to--peerdependencies-) 7- [Add module scripts](#add-module-scripts) 8- [Generate a `tsconfig.json` file with `expo-module-scripts`](#generate-a--tsconfigjson--file-with--expo-module-scripts-) 9- [Various Other Changes](#various-other-changes) 10 11## Change Import 12 13To optimize our libraries for _dead code elimination_ we should migrate our exports to be imported as such: 14 15```diff 16 17- import { FileSystem } from 'expo-file-system'; 18 19+ import * as FileSystem from 'expo-file-system'; 20 21``` 22 23Ideally we would make the main entry-point of a module be a file named like the module like `build/FileSystem.js` 24 25**`package.json`** 26 27```diff 28- "main": "index.js", 29 30+ "main": "build/<MODULE NAME>.js", 31+ "types": "build/<MODULE NAME>.d.ts", 32``` 33 34To migrate from libraries using different imports, we should add a deprecation notice. 35 36> A lot of libraries are just import from Expo, in these cases we can just the deprecation. Ensure you change all imports across `packages/`, `apps/`, and `docs/`. 37 38**`src/index.ts`** 39 40```ts 41import * as FileSystem from './FileSystem'; 42export * from './FileSystem'; 43 44let wasImportWarningShown = false; 45// @ts-ignore: Temporarily define an export named "FileSystem" for legacy compatibility 46Object.defineProperty(exports, 'FileSystem', { 47 get() { 48 if (!wasImportWarningShown) { 49 console.warn( 50 `The syntax "import { FileSystem } from 'expo-file-system'" is deprecated. Use "import * as FileSystem from 'expo-file-system'" or import named exports instead. Support for the old syntax will be removed in SDK 34.` 51 ); 52 wasImportWarningShown = true; 53 } 54 return FileSystem; 55 }, 56}); 57``` 58 59Then eventually remove the index in favor of the named file. (`src/FileSystem.ts`) 60 61## Testing 62 63Migration should include the addition of a `src/__tests__` which can be run with `yarn test` in the root directory of the package. 64 651. If the package is using the old structure of `test/` for utilities, they should migrate to using `jest-expo`. 66 67**`src/__tests__/<MODULE NAME>-test.ts`** 68 69```diff 70- import { mockPlatformWeb } from '../../test/mocking'; 71 72+ import { mockPlatformWeb } from 'jest-expo'; 73``` 74 752. Add a jest object to the `package.json` 76 77**`package.json`** 78 79```js 80"jest": { 81 "preset": "expo-module-scripts" 82}, 83``` 84 853. Run `yarn test` to run the tests. 86 87### Add the tests to CI 88 89In the root `.circleci/config.yaml` add a step to the job named `expo_sdk`. This should be in alphabetic order with the other testing steps. 90 91**`.circleci/config.yaml`** 92 93```yaml 94- yarn: 95 command: test --maxWorkers 1 96 working_directory: ~/expo/packages/expo-sms 97``` 98 99## Move native `dependencies` to `peerDependencies` 100 101In order to prevent overlapping native code in `node_modules`, we should move any `dependencies` containing native code to `peerDependencies`. 102 103## Add module scripts 104 105**`package.json`** 106 107```js 108"scripts": { 109 "build": "expo-module build", 110 "clean": "expo-module clean", 111 "test": "expo-module test", 112 "prepare": "expo-module prepare", 113 "prepublishOnly": "expo-module prepublishOnly", 114 "expo-module": "expo-module" 115} 116``` 117 118## Generate a `tsconfig.json` file with `expo-module-scripts` 119 120To get the `tsconfig` that we use in all of our modules, run `expo-module prepare` or the yarn script `yarn prepare` (given the script is defined in a module's `package.json`) 121 122**`/tsconfig.json`** 123 124```json 125// @generated by expo-module-scripts 126{ 127 "extends": "expo-module-scripts/tsconfig.base", 128 "compilerOptions": { 129 "outDir": "./build" 130 }, 131 "include": ["./src"], 132 "exclude": ["**/__mocks__/*", "**/__tests__/*"] 133} 134``` 135 136## Various Other Changes 137 138- Remove `babel-preset-expo` 139- Remove `flow` 140- For reusing types across the web implementation's native layer and API layer, types should be moved to a named file with the `.types.ts` extension. There are cases (`expo-av` for example) where you should separate types into smaller files. 141 142[universal-modules]: https://github.com/expo/expo/blob/master/guides/Expo%20Universal%20Module%20Infrastructure.md 143